package org.roma.ninemen;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.Toast;

/**
 * 
 * @author Mathias Larsson and Robin Weidelid
 *
 */
public class GameBoard extends View implements Runnable{

	public static int X_RESOLUTION; // Screen resolution
	public static int Y_RESOLUTION;
	
	public static final int X = 0;
	public static final int Y = 1;
	public static final int RED_MOVE = 0;
	public static final int BLUE_MOVE = 1;
	public static final int RED_REMOVE = 2;
	public static final int BLUE_REMOVE = 3;
	
	private Bitmap screen;
	private Drawable bg;
	private Drawable imageRed;
	private Drawable imageBlue;
	private Canvas offscreen;
	private Context context;
	
	private DateFormat sdf = new SimpleDateFormat("HH:mm dd-MM-yyyy");
	
	private Paint paint = new Paint();
	
	private boolean active;
	private Thread mThread;
	private DatabaseHelper db;
	
	private SharedPreferences pref;
	private String winner = null;
	private int turn = RED_MOVE;
	private int redBricksLeft = 9;
	private int blueBricksLeft = 9;
	private NineMenMorrisRules rules;
	private Brick selectedBrick;
	private Brick[] bricks = new Brick[25];
	private int[][] coord = { {1,1},
			{85,85}, {47,46}, {11,8},
			{147,85}, {147,47}, {147,8},
			{205,85}, {245,48}, {283,8},
			{207,145}, {245,149}, {283,148}, 
			{204,204}, {242,244}, {281,281},
			{146,203}, {146,244}, {146,283},
			{88,204}, {49,242}, {10,283},
			{85,145}, {50,147}, {11,145} };

	public boolean isActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public GameBoard(Context context, int xRes, int yRes) {
		super(context);
		this.context = context;
		X_RESOLUTION = xRes;
		Y_RESOLUTION = yRes;
		paint.setTextSize(32);
		db = new DatabaseHelper(getContext());
		rules = new NineMenMorrisRules();
		screen = Bitmap.createBitmap(X_RESOLUTION, Y_RESOLUTION, Bitmap.Config.ARGB_8888);
		
		offscreen = new Canvas(screen);
		bg = context.getResources().getDrawable(R.drawable.ninemensmorris);
		bg.setBounds(0, 0, 300, 300);
		bg.draw(offscreen);
		
		imageRed = context.getResources().getDrawable(R.drawable.red);
		imageBlue = context.getResources().getDrawable(R.drawable.blue);
		active = true;
		mThread = new Thread(this);
	}

	public void start(){
		mThread = new Thread(this);
		mThread.start();
	}

	public void stop(){
		mThread.stop();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		//super.onDraw(canvas);
		
		Matrix m = new Matrix();
		synchronized (offscreen) {
			canvas.drawBitmap(screen, m, null);
			bg.draw(canvas);
			for(int i = 1; i < 25; i++){
				if(bricks[i] != null)
					bricks[i].draw(canvas);
			}
			if(turn == RED_MOVE || turn == RED_REMOVE){
				paint.setColor(Color.RED);
				canvas.drawText("RED TURN", 90, 350, paint);
			} else{
				paint.setColor(Color.BLUE);
				canvas.drawText("BLUE TURN", 90, 350, paint);
			}
			
			if(winner != null){
				paint.setColor(Color.BLACK);
				canvas.drawText(winner, 30, 30, paint);
			}
			if(redBricksLeft > 0){
				paint.setColor(Color.RED);
				canvas.drawText(""+redBricksLeft, 1, 400, paint);
			}
			if(blueBricksLeft > 0){
				paint.setColor(Color.BLUE);
				canvas.drawText(""+blueBricksLeft, 300, 400, paint);
			}
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();
		
		int x = (int)event.getX();
		int y = (int)event.getY();
		
		switch(action){
			case(MotionEvent.ACTION_DOWN):
				for(int i = 1; i < 25; i++){
					
					if( x < coord[i][X] + Brick.SIZE && x > coord[i][X] - 10 && y < coord[i][Y] + Brick.SIZE && y > coord[i][Y] - 10 ){
						Log.i("Hit! : "+i, "pos: "+coord[i][X]+", "+coord[i][Y]);
						
						if( turn == RED_MOVE ){
							if( redBricksLeft > 0 ){
								if( rules.legalMove(i, 0, NineMenMorrisRules.READ_MOVES) ){
									bricks[i] = new Brick(imageRed,NineMenMorrisRules.READ_MOVES,150,150,coord[i][X],coord[i][Y]);
									bricks[i].setPosition(i);
									--redBricksLeft;
									if(rules.partOfThree(i)){
										Toast.makeText(getContext(), "part of 3, remove a blue brick", Toast.LENGTH_SHORT).show();
										turn = RED_REMOVE;
									} else {
										turn = BLUE_MOVE;
									}
								}
							}else{
								if(selectedBrick == null && bricks[i] != null && bricks[i].getColor() == NineMenMorrisRules.READ_MOVES){
									selectedBrick = bricks[i];
									//Log.i("selected pos : ",""+i);
								}
								else if (selectedBrick != null){
									if( rules.legalMove(i, selectedBrick.getPosition(), NineMenMorrisRules.READ_MOVES) ){
										Log.i("RED from : "+selectedBrick.getPosition(),"to : "+i);
										
										rules.remove(selectedBrick.getPosition(), NineMenMorrisRules.READ_MARKER);
										bricks[i] = selectedBrick;
										bricks[i].setDestination(coord[i][X], coord[i][Y]);
										bricks[selectedBrick.getPosition()] = null;
										bricks[i].setPosition(i);
										selectedBrick = null;
										if(rules.partOfThree(i)){
											Toast.makeText(getContext(), "part of 3, remove a blue brick", Toast.LENGTH_SHORT).show();
											turn = RED_REMOVE;
										} else {
											turn = BLUE_MOVE;
										}
										
									} else {
										selectedBrick = null;
										Toast.makeText(getContext(), "invalid move, red FOOL!", Toast.LENGTH_SHORT).show();
									}
								} else {
									Toast.makeText(getContext(), "choose your RED poison", Toast.LENGTH_SHORT).show();
								}
							}
						} else if (turn == BLUE_MOVE) {
							if( blueBricksLeft > 0 ){
								if( rules.legalMove(i, 0, NineMenMorrisRules.BLUE_MOVES) ){
									bricks[i] = new Brick(imageBlue,NineMenMorrisRules.BLUE_MOVES,150,150,coord[i][X],coord[i][Y]);
									bricks[i].setPosition(i);
									--blueBricksLeft;
									if(rules.partOfThree(i)){
										Toast.makeText(getContext(), "part of 3, remove a red brick", Toast.LENGTH_SHORT).show();
										turn = BLUE_REMOVE;
									} else {
										turn = RED_MOVE;
									}
								}
							}else{
								if(selectedBrick == null && bricks[i] != null && bricks[i].getColor() == NineMenMorrisRules.BLUE_MOVES){
									selectedBrick = bricks[i];
									Log.i("selected pos : ",""+i);
								}
								else if (selectedBrick != null) {
									if( rules.legalMove(i, selectedBrick.getPosition(), NineMenMorrisRules.BLUE_MOVES) ){
										Log.i("BLUE from : "+selectedBrick.getPosition(),"to : "+i);
										rules.remove(selectedBrick.getPosition(), NineMenMorrisRules.BLUE_MARKER);
										bricks[i] = selectedBrick;
										bricks[i].setDestination(coord[i][X], coord[i][Y]);
										bricks[selectedBrick.getPosition()] = null;
										bricks[i].setPosition(i);
										selectedBrick = null;
										if(rules.partOfThree(i)){
											Toast.makeText(getContext(), "part of 3, remove a red brick", Toast.LENGTH_SHORT).show();
											turn = BLUE_REMOVE;
										} else {
											turn = RED_MOVE;
										}
									} else{
										selectedBrick = null;
										Toast.makeText(getContext(), "invalid move, blue FOOL!", Toast.LENGTH_SHORT).show();
									}
								} else {
									Toast.makeText(getContext(), "choose your BLUE poison", Toast.LENGTH_SHORT).show();
								}
							}
						} else if (turn == RED_REMOVE){
							
							if( !rules.partOfThree(i) ){
								if( rules.remove(i, NineMenMorrisRules.BLUE_MARKER) ){
									bricks[i] = null;
									turn = BLUE_MOVE;
								} else {
									Toast.makeText(getContext(), "dont remove your own brick(red)", Toast.LENGTH_SHORT).show();
								}
							} else {
								Toast.makeText(getContext(), "choose a blue brick not part of a mill", Toast.LENGTH_SHORT).show();
							}
							
						} else if (turn == BLUE_REMOVE){
							if( !rules.partOfThree(i) ){
								if( rules.remove(i, NineMenMorrisRules.READ_MARKER) ){
									bricks[i] = null;
									turn = RED_MOVE;
								} else {
									Toast.makeText(getContext(), "dont remove your own brick(blue)", Toast.LENGTH_SHORT).show();
								}
							} else {
								Toast.makeText(getContext(), "choose a red brick not part of a mill", Toast.LENGTH_SHORT).show();
							}
						}
					}
				}
				//red lost?
				if ( rules.lost(NineMenMorrisRules.READ_MARKER) ){
					winner = "BLUE IS WINNER";
					Log.i("Winner","Blue");
					winnerDialog();
				}
				//blue lost?
				else if ( rules.lost(NineMenMorrisRules.BLUE_MARKER) ){
					winner = "RED IS WINNER";
					Log.i("Winner","Red");
					winnerDialog();
				}
			return true;
		}
		return false;
	}
	
	public void save(int pos){
		rules.setTherealdeal(turn);
		db.saveGame(pos, sdf.format(new Date()), turn, rules);
	}
	
	public void load(int pos){
		if(db.loadGame(pos) != null){
			winner = null;
			rules = db.loadGame(pos);
			bricks = new Brick[25];
			redBricksLeft = rules.getRedmarker();
			blueBricksLeft = rules.getBluemarker();
			turn = rules.getTherealdeal();
			
			int[] gameplan = rules.getGameplan();
			for(int i = 1; i < 25; i++){
				if( gameplan[i] == NineMenMorrisRules.READ_MARKER ){
					bricks[i] = new Brick(imageRed, coord[i][X], coord[i][Y]);
					bricks[i].setColor(NineMenMorrisRules.READ_MOVES);
					bricks[i].setPosition(i);
				} else if ( gameplan[i] == NineMenMorrisRules.BLUE_MARKER ){
					bricks[i] = new Brick(imageBlue, coord[i][X], coord[i][Y]);
					bricks[i].setColor(NineMenMorrisRules.BLUE_MOVES);
					bricks[i].setPosition(i);
				}
			}
		}else{
			Toast.makeText(getContext(), "Couldnt load game", Toast.LENGTH_SHORT).show();
		}
	}
	
	public void reset(){
		winner = null;
		rules = new NineMenMorrisRules();
		pref = context.getSharedPreferences(NineMenRoMaActivity.SHAREDPREF, NineMenRoMaActivity.MODE_PRIVATE);
		rules.setRedmarker( pref.getInt("numberOfRedBricks", 9) );
		rules.setBluemarker( pref.getInt("numberOfBlueBricks", 9) );
		bricks = new Brick[25];
		redBricksLeft = rules.getRedmarker();
		blueBricksLeft = rules.getBluemarker();
		turn = RED_MOVE;
	}

	public void run() {
		while (true) {
			this.postInvalidate();
			try {
				Thread.sleep(40);
			} catch (Exception e) {
				Log.e("Thread trasig", "error, error. emergency!");
			}
		}

	}
	
	public void winnerDialog(){
		
		AlertDialog alertDialog = new AlertDialog.Builder(getContext()).create();
		alertDialog.setTitle("Winner!");
		if(winner != null)
			alertDialog.setMessage(winner);
		
		alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
		      public void onClick(DialogInterface dialog, int which) {
		    	  reset();
		    } }); 
		alertDialog.show();
	}
	
	

}
